/*
 * Password Strength (0.1.1)
 * by Sagie Maoz (n0nick.net)
 * n0nick@php.net
 *
 * This plugin will check the value of a password field and evaluate the
 * strength of the typed password. This is done by checking for
 * the diversity of character types: numbers, lowercase and uppercase
 * letters and special characters.
 *
 * Copyright (c) 2010 Sagie Maoz <n0nick@php.net>
 * Licensed under the GPL license, see http://www.gnu.org/licenses/gpl-3.0.html
 *
 *
 * NOTE: This script requires jQuery to work.  Download jQuery at www.jquery.com
 *
 */
(function($){

var passwordStrength = new function() {
	this.countRegexp = function(val, rex) {
		var match = val.match(rex);
		return match ? match.length : 0;
	};

	this.getStrength = function(val, minLength)	{
		var len = val.length;

		// too short =(
		if (len < minLength) {
			return 0;
		}

		var nums = this.countRegexp(val, /\d/g),
			lowers = this.countRegexp(val, /[a-z]/g),
			uppers = this.countRegexp(val, /[A-Z]/g),
			specials = len - nums - lowers - uppers;

		// just one type of characters =(
		if (nums == len || lowers == len || uppers == len || specials == len) {
			return 1;
		}

		var strength = 0;
		if (nums)	{ strength+= 2; }
		if (lowers)	{ strength+= uppers? 4 : 3; }
		if (uppers)	{ strength+= lowers? 4 : 3; }
		if (specials) { strength+= 5; }
		if (len > 10) { strength+= 1; }

		return strength;
	};

	this.getStrengthLevel = function(val, minLength) {
		var strength = this.getStrength(val, minLength);
		switch (true) {
			case (strength <= 0):
				return 1;
				break;
			case (strength > 0 && strength <= 4):
				return 2;
				break;
			case (strength > 4 && strength <= 8):
				return 3;
				break;
			case (strength > 8 && strength <= 12):
				return 4;
				break;
			case (strength > 12):
				return 5;
				break;
		}

		return 1;
	};
}

$.fn.password_strength = function(options) {
	var settings = $.extend({
		'container' : null,
		'minLength' : 6,
		'texts' : {
			1 : 'Too weak',
			2 : 'Weak password',
			3 : 'Normal strength',
			4 : 'Strong password',
			5 : 'Very strong password'
		}
	}, options);

	return this.each(function() {
		$(this).keyup(function() {
            var container = defineContainer(this),
			    val = $(this).val();

			if (val.length > 0) {
				var level = passwordStrength.getStrengthLevel(val, settings.minLength);
				var class = 'password_strength_' + level;

				if (!container.hasClass(class) && level in settings.texts) {
					container.text(settings.texts[level]).attr('class', 'password_strength ' + class);
				}
			} else {
				container.text('').attr('class', 'password_strength');
			}
		});
	});

    function defineContainer(elem) {
        var container;
        if (settings.container) {
			container = $(settings.container);
		} else {
            container = $(elem).parent().find('.password_strength');
            if (container.length == 0) {
			    container = $('<span/>').attr('class', 'password_strength');
			    $(elem).after(container);
            }
		}
        return container;
    }
};

})(jQuery);



